package ace.module.oss.core.impl.manager.impl;

import ace.cmp.json.api.JsonService;
import ace.module.oss.api.enums.OssSupplierTypeEnum;
import ace.module.oss.core.impl.dao.entity.OssApplicationConfig;
import ace.module.oss.core.impl.dao.entity.OssSupplier;
import ace.module.oss.core.impl.manager.OssManager;
import ace.module.oss.core.impl.manager.OssManagerFactory;
import ace.module.oss.core.impl.manager.impl.ossmgr.AliyunOssManager;
import ace.module.oss.core.impl.manager.impl.ossmgr.MinIoOssManager;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.x.file.storage.core.FileStorageProperties;
import org.dromara.x.file.storage.core.FileStorageService;
import org.dromara.x.file.storage.core.FileStorageServiceBuilder;
import org.dromara.x.file.storage.core.file.FileWrapperAdapter;
import org.springframework.stereotype.Component;

/**
 * @author caspar
 * @date 2024/5/21 11:46
 */
@Slf4j
@AllArgsConstructor
@Component
public class OssManagerFactoryImpl implements OssManagerFactory {
  private final JsonService jsonService;
  private final List<FileWrapperAdapter> fileWrapperAdapterList;

  @Override
  public OssManager get(OssApplicationConfig ossApplicationConfig, OssSupplier ossSupplier) {
    if (OssSupplierTypeEnum.OSS_ALIYUN.getCode().equals(ossSupplier.getType())) {
      return this.getAliyunOss(ossApplicationConfig, ossSupplier);
    } else if (OssSupplierTypeEnum.OSS_MINIO.getCode().equals(ossSupplier.getType())) {
      return this.getMinIoOss(ossApplicationConfig, ossSupplier);
    } else {
      throw new RuntimeException("无法解析的type:" + ossSupplier.getType());
    }
  }

  private OssManager getMinIoOss(
      OssApplicationConfig ossApplicationConfig, OssSupplier ossSupplier) {
    FileStorageProperties.MinioConfig config =
        this.jsonService.toObject(ossSupplier.getConfig(), FileStorageProperties.MinioConfig.class);
    FileStorageProperties properties = new FileStorageProperties();
    properties.setDefaultPlatform(config.getPlatform());
    properties.setMinio(List.of(config));
    FileStorageService fileStorageService = this.getFileStorageService(properties);
    return new MinIoOssManager(ossApplicationConfig, ossSupplier, fileStorageService);
  }

  private OssManager getAliyunOss(
      OssApplicationConfig ossApplicationConfig, OssSupplier ossSupplier) {
    FileStorageProperties.AliyunOssConfig config =
        this.jsonService.toObject(
            ossSupplier.getConfig(), FileStorageProperties.AliyunOssConfig.class);
    FileStorageProperties properties = new FileStorageProperties();
    properties.setDefaultPlatform(config.getPlatform());
    properties.setAliyunOss(List.of(config));
    FileStorageService fileStorageService = this.getFileStorageService(properties);
    return new AliyunOssManager(ossApplicationConfig, ossSupplier, fileStorageService);
  }

  private FileStorageService getFileStorageService(FileStorageProperties properties) {
    FileStorageServiceBuilder builder = FileStorageServiceBuilder.create(properties).useDefault();

    for (FileWrapperAdapter fileWrapperAdapter : fileWrapperAdapterList) {
      builder.addFileWrapperAdapter(fileWrapperAdapter);
    }

    return builder.build();
  }
}
